package cx.ath.skyflyer.chart;

import java.util.Enumeration;
import java.util.Vector;

/**
 *
 * @author lego
 */
public class DataSeries {

    public DataSeries(String name) {
        this.Name = name;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color c) {
        color = c;
    }

    public void add(DataPoint p)
            throws IllegalArgumentException {

        if (!pts.isEmpty()) {
            DataPoint dp = (DataPoint)pts.lastElement();
            if (p.x <= dp.x)
                throw new IllegalArgumentException("New data point should be after the last one.");
        }

        pts.addElement(p);
    }

    /**
     * Finds a data point with minimum Y between given X values.
     * @param minX
     * @param maxX
     * @return
     */
    public DataPoint minY(double minX, double maxX) {
        if (maxX < minX)
            return null;

        if (pts.isEmpty())
            return null;

        int minIndex = binarySearch(minX, 0, pts.size());
        int maxIndex = binarySearch(maxX, 0, pts.size());

        DataPoint res = null;
        for (int i = minIndex; i <= maxIndex && i < pts.size(); ++i) {
            DataPoint pt = (DataPoint)pts.elementAt(i);
            if (res == null || pt.y < res.y)
                res = pt;
        }

        return res;
    }

    /**
     * Finds a data point with minimum Y between given X values.
     * @param minX
     * @param maxX
     * @return
     */
    public DataPoint maxY(double minX, double maxX) {
        if (maxX < minX)
            return null;

        if (pts.isEmpty())
            return null;
        
        int minIndex = binarySearch(minX, 0, pts.size());
        int maxIndex = binarySearch(maxX, 0, pts.size());

        DataPoint res = null;
        for (int i = minIndex; i <= maxIndex && i < pts.size(); ++i) {
            DataPoint pt = (DataPoint)pts.elementAt(i);
            if (res == null || pt.y > res.y)
                res = pt;
        }

        return res;
    }

    /**
     * Searched for index where x should be inserted to keep the pts sorted.
     * @param x
     * @param lower
     * @param upper
     * @return
     */
    private int binarySearch(double x, int lower, int upper) {
        int size = upper - lower;
        int mid = lower + size / 2;

        if (size <= 1)
            return lower;

        final double test = ((DataPoint)pts.elementAt(mid)).x;
        if (x < test)
            return binarySearch(x, lower, mid);

        if (x > test)
            return binarySearch(x, mid, upper);

        return mid;
    }

    public Enumeration points() {
        return pts.elements();
    }
    private Color color = new Color(255, 0, 0);
    private final Vector pts = new Vector();
    public final String Name;
}
